<?php
namespace app\index\controller;

use app\common\controller\Front;

use think\Db;

//1.5.20~~~1.6.0

class Update extends Front
{
    private $version = '1.6.0';
    
	//第一步升级表结构	
	public function index()
    {
        if(is_file('./datas/db/'.$this->version.'.lock')){
			return '已经是最新版，不需要再次升级，建议删除该文件./apps/index/controller/Update.php';
		}
        
		if(config('database.type') == 'sqlite'){
            $this->_sqlite();
        }else{
            $this->_mysql();
        }
        
        $this->configClear();
        
        return '<a href="'.DcUrl('index/update/data','','').'">数据库结构升级完成，请点击这里迁移数据</a>';
	}
    
    //第二步迁移数据
    public function data()
    {
        if(is_file('./datas/db/'.$this->version.'.lock')){
			return '已经是最新版，不需要再次升级，建议删除该文件./apps/index/controller/Update.php';
		}
        
        if(config('database.type') == 'mysql'){
            $this->mysqlData();
        }else{
            $this->sqliteData();
        }
        
        touch('./datas/db/'.$this->version.'.lock');
        
        return '恭喜您，升级完成';
    }
    
    private function _mysql()
    {
        //数库库结构信息
        $tables = $this->tablesInfo();
        
        //数据库前缀 修改term_map表字段
        $prefix = config('database.prefix');
        
        //定义变量
        $sql = [];
        
        //term表字段
        $fields = array_flip($tables['fields'][$prefix.'term']);
        if( !isset($fields['term_type']) ){
            array_push($sql, "ALTER TABLE ".$prefix."term Add term_type VARCHAR(100) NULL AFTER `term_order`;");
            array_push($sql,"CREATE INDEX term_type ON ".$prefix."term(term_type);");//增加索引
        }
        if( !isset($fields['term_info']) ){
            array_push($sql, "ALTER TABLE ".$prefix."term Add term_info TEXT NULL AFTER `term_type`;");
        }
        if( !isset($fields['term_parent']) ){
            array_push($sql, "ALTER TABLE ".$prefix."term Add term_parent BIGINT(20) NOT NULL DEFAULT '0' AFTER `term_info`;");
            array_push($sql,"CREATE INDEX term_parent ON ".$prefix."term(term_parent);");//增加索引
        }
        if( !isset($fields['term_count']) ){
            array_push($sql, "ALTER TABLE ".$prefix."term Add term_count INT(11) NOT NULL DEFAULT '0' AFTER `term_parent`;");
        }
         //term表索引
        $index = array_flip($tables['index'][$prefix.'term']);
        //增加索引
        if( !isset($index['term_module']) ){
            array_push($sql,"CREATE INDEX term_module ON ".$prefix."term(term_module);");
        }
        
        //term_map表字段
        $fields = array_flip($tables['fields'][$prefix.'term_map']);
        if( isset($fields['term_much_id']) ){
            array_push($sql,"ALTER TABLE `".$prefix."term_map` CHANGE `term_much_id` `term_id` BIGINT(20) NULL DEFAULT '0';");
        }
        //term_map表索引
        $index = array_flip($tables['index'][$prefix.'term_map']);
        //删除索引
        if( isset($index['term_much_id']) ){
            array_push($sql,"DROP INDEX term_much_id ON ".$prefix."term_map;");
        }
        if( isset($index['detail_id']) ){
            array_push($sql,"DROP INDEX detail_id ON ".$prefix."term_map;");
        }
        //增加索引
        if( !isset($index['map_term_id']) ){
            array_push($sql,"CREATE INDEX map_term_id ON ".$prefix."term_map(term_id);");
        }
        if( !isset($index['map_info_id']) ){
            array_push($sql,"CREATE INDEX map_info_id ON ".$prefix."term_map(detail_id);");
        }
        
        //执行SQL语句
        //dump($sql);
        $this->executeSql($sql);
    }
    private function mysqlData()
    {
        //迁移旧数据与新增数据等
        $this->dataUpdate();
        
        //数据库前缀 修改term_map表字段
        $prefix = config('database.prefix');
        
        //SQL语句变量
        $sql = [];
        
        //删除废弃表
        array_push($sql,"DROP TABLE IF EXISTS `".$prefix."term_much`;");
        
        //执行SQL语句
        //dump($sql);
        $this->executeSql($sql);
    }
    
    private function _sqlite()
    {
        //数库库结构信息
        $tables = $this->tablesInfo();
        
        //数据库前缀 修改term_map表字段
        $prefix = config('database.prefix');
        
        //定义变量
        $sql = [];
        
        //term_map表索引（删除不需要的索引）
        $index = array_flip($tables['index'][$prefix.'term_map']);
        //删除索引
        if( isset($index['term_much_id']) ){
            array_push($sql,"DROP INDEX term_much_id;");
        }
        if( isset($index['detail_id']) ){
            array_push($sql,"DROP INDEX detail_id;");
        }
        //term_map表（修改字段类型）
        $fields = array_flip($tables['fields'][$prefix.'term_map']);
        if( isset($fields['term_much_id']) ){
            array_push($sql, "ALTER TABLE ".$prefix."term_map RENAME TO temp_term_map;");//把原表改成暂存表
            array_push($sql, "CREATE TABLE ".$prefix."term_map(detail_id INTEGER DEFAULT '0' NULL, term_id INTEGER DEFAULT '0' NULL);");//建新表
            array_push($sql, "INSERT INTO ".$prefix."term_map SELECT * FROM temp_term_map;");//将暂存表数据写入到新表
            array_push($sql, "DROP TABLE temp_term_map;");//删除暂存表
            //array_push($sql, "CREATE TABLE newTb as select * from oldTb;");//复制表结构与数据
        }
        //增加索引
        if( !isset($index['map_term_id']) ){
            array_push($sql,"CREATE INDEX map_term_id ON [".$prefix."term_map](term_id);");
        }
        if( !isset($index['map_info_id']) ){
            array_push($sql,"CREATE INDEX map_info_id ON [".$prefix."term_map](detail_id);");
        }
        
        //term表字段（增加字段）
        $fields = array_flip($tables['fields'][$prefix.'term']);
        if( !isset($fields['term_type']) ){
            array_push($sql, "ALTER TABLE ".$prefix."term Add term_type VARCHAR(100) NULL;");
        }
        if( !isset($fields['term_info']) ){
            array_push($sql, "ALTER TABLE ".$prefix."term Add term_info TEXT NULL;");
        }
        if( !isset($fields['term_parent']) ){
            array_push($sql, "ALTER TABLE ".$prefix."term Add term_parent INTEGER DEFAULT '0' NULL;");
        }
        if( !isset($fields['term_count']) ){
            array_push($sql, "ALTER TABLE ".$prefix."term Add term_count INTEGER DEFAULT '0' NULL;");
        }
        //term表索引(新增索引)
        $index = array_flip($tables['index'][$prefix.'term']);
        if( !isset($index['term_type']) ){
            array_push($sql, "CREATE INDEX term_type ON [".$prefix."term](term_type ASC);");
        }
        if( !isset($index['term_parent']) ){
            array_push($sql, "CREATE INDEX term_parent ON [".$prefix."term](term_parent ASC);");
        }
        
        //执行升级语句
        //dump($sql);
        $this->executeSql($sql);
    }
    private function sqliteData()
    {
        //迁移旧数据与新增数据等
        $this->dataUpdate();
        
        //数库库结构信息
        $tables = $this->tablesInfo();
        
        //数据库前缀
        $prefix = config('database.prefix');
        
        //SQL语句变量
        $sql = [];
        
        //term_much表（先删除索引）
        $index = array_flip($tables['index'][$prefix.'term_much']);
        if( isset($index['term_id_index']) ){
            array_push($sql, "DROP INDEX term_id_index;");
        }
        if( isset($index['term_much_type']) ){
            array_push($sql, "DROP INDEX term_much_type;");
        }
        //term_much（删除废弃的表）
        if($tables['fields'][$prefix.'term_much']){
            array_push($sql, "DROP TABLE ".$prefix."term_much;");
        }
        //执行升级语句
        //dump($sql);
        $this->executeSql($sql);
    }
    
    //默认数据处理
    private function dataUpdate()
    {
        //迁移分类表旧数据
        $data = [];
        foreach(db('term_much')->select() as $key=>$value){
            $data[$key]['term_id']     = $value['term_id'];
            $data[$key]['term_type']   = $value['term_much_type'];
            $data[$key]['term_info']   = $value['term_much_info'];
            $data[$key]['term_parent'] = DcEmpty($value['term_much_parent'],0);
            $data[$key]['term_count']  = $value['term_much_count'];
        }
        $result = model('common/Term')->isUpdate()->saveAll($data);
        
        //批量添加权限
        $result = \daicuo\Op::save_all([
            [
                'op_name'       => 'editor',
                'op_value'      => 'admin/addon/index?action=index',
                'op_module'     => 'common',
                'op_controll'   => 'system',
                'op_action'     => 'auth',
                'op_order'      => 0,
                'op_status'     => 'normal',
            ],
            [
                'op_name'       => 'editor',
                'op_value'      => 'admin/addon/index?action=create',
                'op_module'     => 'common',
                'op_controll'   => 'system',
                'op_action'     => 'auth',
                'op_order'      => 0,
                'op_status'     => 'normal',
            ],
            [
                'op_name'       => 'editor',
                'op_value'      => 'admin/addon/index?action=edit',
                'op_module'     => 'common',
                'op_controll'   => 'system',
                'op_action'     => 'auth',
                'op_order'      => 0,
                'op_status'     => 'normal',
            ],
            [
                'op_name'       => 'editor',
                'op_value'      => 'admin/addon/index?action=save',
                'op_module'     => 'common',
                'op_controll'   => 'system',
                'op_action'     => 'auth',
                'op_order'      => 0,
                'op_status'     => 'normal',
            ],
            [
                'op_name'       => 'editor',
                'op_value'      => 'admin/addon/index?action=update',
                'op_module'     => 'common',
                'op_controll'   => 'system',
                'op_action'     => 'auth',
                'op_order'      => 0,
                'op_status'     => 'normal',
            ],
        ]);
        
    }
    
    //执行SQL语句
    private function executeSql($sql){
        foreach($sql as $key=>$value){
            \think\Db::execute($value); 
            dump('执行语句 >> '.$value);
        }
    }
    
    //获取数据表信息
    private function tablesInfo()
    {
        $tables = [];
        
        //mysql数据库结构
        if(config('database.type') == 'mysql'){
            //$tables  = Db::query("show tables");
            foreach(Db::query("SHOW TABLE STATUS") as $key=>$table){
                //表字段
                $tables['fields'][$table['Name']] = Db::getTableInfo($table['Name'],'fields');
                //表索引
                $index = Db::query("show index from ".$table['Name']);
                $tables['index'][$table['Name']] = array_column($index, 'Key_name');
            }
            return $tables;
        }
        
        //sqlite3数据库结构
        //dump(Db::query("select * from sqlite_master"));
        //表字段
        foreach(Db::query("select * from sqlite_master where type='table'") as $key=>$table){
            if($table['name'] == 'sqlite_sequence'){
                continue;
            }
            $tables['fields'][$table['name']] = Db::getTableInfo($table['name'],'fields');
        }
        //表索引
        foreach(Db::query("select * from sqlite_master where type = 'index'") as $key=>$table){
            $tables['index'][$table['tbl_name']][] = $table['name'];
        }
        return $tables;
    }
    
    //清空缓存
    private function configClear()
    {
        $file = new \files\File();
        
        $file->d_delete(LOG_PATH);
        
        $file->d_delete(CACHE_PATH);
        
        $file->d_delete(TEMP_PATH);
    }
}